/* Copyright (C) 2007-2008  klevgert  http://code.google.com/p/db4o-netbeans/

This file is part of the db4o-netbeans module suite.

db4o-netbeans is free software; you can redistribute it and/or modify it under
the terms of version 2 of the GNU General Public License as published
by the Free Software Foundation and as clarified by db4objects' GPL 
interpretation policy, available at
http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
Suite 350, San Mateo, CA 94403, USA.

db4o-netbeans is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. */

package com.db4o.nb.api.impl;

import com.db4o.*;
import com.db4o.messaging.*;

/**
 * starts a db4o server with the settings from {@link ServerConfiguration}. 
 * <br><br>This is a typical setup for a long running server.
 * <br><br>The Server may be stopped from a remote location by running
 * StopServer. The StartServer instance is used as a MessageRecipient and
 * reacts to receiving an instance of a StopServer object.
 * <br><br>Note that all user classes need to be present on the server
 * side and that all possible Db4o.configure() calls to alter the db4o
 * configuration need to be executed on the client and on the server.
 */
public class StartServer
    implements MessageRecipient {
  
  /**
   * setting the value to true denotes that the server should be closed
   */
  private boolean stop = false;
  
  /**
   * starts a db4o server using the configuration from
   * {@link ServerConfiguration}.
   */
  public static void main(String[] arguments) {
    
    String file = arguments[0];
    String port = arguments[1];
    String user = arguments[2];
    String password = arguments[3]; 
    new StartServer().runServer( file, port, user, password );
  } 
  
  /**
   * opens the ObjectServer, and waits forever until close() is called
   * or a StopServer message is being received.
   */
  public void runServer( String file, String port, String user, String password ){
    synchronized(this){
      ObjectServer db4oServer = Db4o.openServer(file, Integer.parseInt(port) );
      db4oServer.grantAccess(user, password);
      
      // Using the messaging functionality to redirect all
      // messages to this.processMessage
      db4oServer.ext().configure().clientServer().setMessageRecipient(this);

      // to identify the thread in a debugger
      Thread.currentThread().setName(this.getClass().getName());
      
      // We only need low priority since the db4o server has
      // it's own thread.
      Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
      try {
          if(! stop){
            System.out.println("Server: Up and Running.");
            // wait forever for notify() from close()
            this.wait(Long.MAX_VALUE);   
            System.out.println("Server: Signal received to terminate.");
          }
      } catch (Exception e) {
        e.printStackTrace();
      }
      db4oServer.close();
    }
  }
  
  /**
   * messaging callback
   * @see com.db4o.messaging.MessageRecipient#processMessage(ObjectContainer, Object)
   */
  public void processMessage(ObjectContainer con, Object message) {
//    System.out.println( (message==null)? "<null>" : message.toString());
    close();
  }
  
  /**
   * closes this server.
   */
  public void close(){
    synchronized(this){
      stop = true;
      this.notify();
    }
  }
}
